package com.sen.common.common.util;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

import java.util.List;
import java.util.Set;
import java.util.TreeSet;

/**
 * @author esjiang
 */
public abstract class TreeUtils {

    static String default_parent_code_name = "parentCode";
    static String default_code_name = "code";
    static String default_children_name = "children";

    /**
     * 构建树结构
     * 对象必须要有code、parentCode、children属性
     *
     * @param parentCode
     * @param nodes
     * @param array
     * @param <T>
     */
    public static <T extends Comparable> void buildTree(String parentCode, List<T> nodes, Set<T> array) {
        buildTree(parentCode, nodes, array, default_parent_code_name, default_code_name, default_children_name);
    }

    /**
     * 构建树结构
     *
     * @param parentCode
     * @param nodes
     * @param array
     * @param parentFieldName   父节点属性名称
     * @param fieldName         节点属性名称
     * @param childrenFieldName 子节点集合属性名称
     * @param <T>               必须实现Comparable接口
     */
    public static <T extends Comparable> void buildTree(String parentCode, List<T> nodes, Set<T> array, String parentFieldName, String fieldName, String childrenFieldName) {
        for (T node : nodes) {
            if (StrUtil.equals(Convert.toStr(ReflectUtil.getFieldValue(node, parentFieldName)), parentCode)) {
                array.add(node);
                Object children = ReflectUtil.getFieldValue(node, childrenFieldName);
                if (ObjectUtil.isNull(children)) {
                    children = new TreeSet<>();
                    ReflectUtil.setFieldValue(node, childrenFieldName, children);
                }
                buildTree(Convert.toStr(ReflectUtil.getFieldValue(node, fieldName)), nodes, (Set<T>) children, parentFieldName, fieldName, childrenFieldName);
            }
        }
    }
}
